#coding=utf-8
#coding=utf-8
from robot.api import ExecutionResult,ResultVisitor
import os
import sys
import logging
import smtplib
import ruamel.yaml
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr

logger = logging.getLogger(__name__)



class TestSuits(ResultVisitor):
    def visit_suite(self,suite):   
        global suite_name, suite_status,suite_elapsedtime,case_name,case_status,case_elapsedtime,case_message,sub_suites
        suite_name = suite.name
        suite_status = suite.status
        suite_elapsedtime = suite.elapsedtime
        sub_suites = suite.suites
        case_name =[]
        case_status=[]
        case_elapsedtime=[]
        case_message = []
        for sub_suite in sub_suites:
            for l2_suite in  sub_suite.suites:
                tests = l2_suite.tests
                for test in tests:
                        case_name.append(test.name)
                        case_status.append(test.status)
                        case_elapsedtime.append(test.elapsedtime)
                        case_message.append(test.message)
                    
# Sending Email     
class EmailSending():
    
    def __init__(self,
        config_yaml_file='./lib/Mail/mail.yml',
        mail_file='./lib/Mail/mail.html'):
        self.mail_file = self.read_file_as_string(mail_file)
        self.parse_config_data(config_yaml_file)
        self.mail_subject = '%s' % (self.mail_title)

    def parse_config_data(self, config_yaml_file):
        file_obj = open(config_yaml_file, 'r')
        config_data = ruamel.yaml.load(file_obj, ruamel.yaml.RoundTripLoader)
        file_obj.close()
        # Meta data
        self.mail_sender = config_data['Mail Sender']
        self.mail_server = config_data['Mail Server']
        self.mail_host = config_data['Mail Host']
        self.mail_user = config_data['Mail User']
        self.mail_pass = config_data['Mail Pass']
        self.mail_tls = config_data['Mail TLS']
        self.mail_title = config_data['Mail Title']
        self.mail_to_all = config_data['Mail To ALL']

    def email_sending(self):
        msg = MIMEMultipart()
        msg['From'] = self.mail_sender
        msg['To'] = ",".join(self.mail_to_all)
        mail_to = self.mail_to_all
        msg['Subject'] = Header(self.mail_subject).encode()
        msg.attach(MIMEText('{}'.format(self.mail_file), 'html', 'utf-8'))
        try:
            server = smtplib.SMTP_SSL(self.mail_server)
            logger.info(server.ehlo())
            server.login(self.mail_user, self.mail_pass)
            server.sendmail(self.mail_sender, mail_to, msg.as_string())
            server.quit()
        except Exception as e:
            logger.error("Email sending failed. Error: {}".format(repr(e)))

    def read_file_as_string(self, file):
        contents = open(file, 'r', encoding='UTF-8').read()
        return contents

# Get the template and write to email
class EmailTemplate():
    
    def __init__(self, robot_dict, template):
        self.robot_dict = robot_dict
        self.template = template
        self.case_list = ""

    def write_to_html(self):
        file_data = ""
        self.get_html_test_case_list(self.robot_dict)
        with open(self.template, "r", encoding="utf-8") as f:
            for line in f:
                if "__test_status__" in line:
                    line = line.replace("__test_status__", suite_status)
                elif "__test_status_color__" in line:
                    test_status_color = "green"
                    if suite_status == "FAIL":
                        test_status_color = "red"
                    line = line.replace("__test_status_color__", test_status_color)
                elif "__test_logo__" in line:
                    test_logo = "height: 32px; width: 32px; border-radius: 50%; " \
                        + "display: inline-block; background-image: "
                    if suite_status == "FAIL":
                        test_logo += "radial-gradient(#FF1111, #FF7777, #FFCCDD);"
                    else:
                        test_logo += "radial-gradient(#00FF00, #55FF77, #BBFFEE);"
                    line = line.replace("__test_logo__", test_logo)
                elif "__test_suite_name__" in line:
                    line = line.replace("__test_suite_name__", 
                       suite_name)
                elif "__test_duration__" in line:
                    line = line.replace("__test_duration__", 
                        r"%s hr %s min %s sec" % (
                            suite_elapsedtime // 3600000, 
                            (suite_elapsedtime % 3600000 //60000) , 
                            suite_elapsedtime % 3600000 % 60000 // 1000))
                elif "__test_case_total__" in line:
                    line = line.replace("__test_case_total__", str(stats.total.total))
                elif "__test_case_passed__" in line:
                    line = line.replace("__test_case_passed__", str(stats.total.passed))
                elif "__test_case_failed__" in line:
                    line = line.replace("__test_case_failed__", str(stats.total.failed))
                elif "__test_pass_rate__" in line:
                    line = line.replace("__test_pass_rate__", "%.2f" % 
                        (stats.total.passed * 100 / stats.total.total))
                elif "__test_suite_l2_and_case_list__" in line:
                    line = line.replace("__test_suite_l2_and_case_list__", 
                        self.case_list)
                    logger.info(line)                                                                                                                                 
                    pass
                file_data += line
            logger.info("Email template content: \n %s \n" % file_data)
        with open(self.template, "w", encoding="utf-8") as f:
            f.write(file_data)

    def get_html_test_case_list(self,num):
        l=len(case_name)
        for num in range(l):
            if case_status[num] =='PASS':
                case_status[num] =  '<font color="#32CD32">'+ 'PASS'+'</font> '
            elif case_status[num] =='FAIL':
                case_status[num] =  '<font color="#FF0000">'+'FAIL'+'</font> '
            self.case_list += '      <tr>\n' \
                '        <td>\n          ' + \
                str(num+1) + \
                '\n        </td>\n' \
                '        <td>\n          ' + \
                case_name[num] + \
                '\n        </td>\n' \
                     '<td>\n          ' + \
                case_status[num] + \
                '\n        </td>\n' \
                '        <td>\n          ' + \
                str(int((case_elapsedtime[num]/(1000*60)) % 60)) +'min'+ \
                '\n        </td>\n' \
                '<td>\n          ' + \
                case_message[num] + \
                '\n        </td>\n' \
                '      </tr>\n'

def main():
    global   stats
    outputxmlfile = sys.argv[1]
    # global env
    # env = sys.argv[2]
    # outputxmlfile = 'finaloutput.xml'
    # 1. get test results from output.xml
    result = ExecutionResult(outputxmlfile)
    result.configure(stat_config={'suite_stat_level': 2,
                              'tag_stat_combine': 'tagANDanother'})
    stats = result.statistics
    # 2. send email for notification
    sep = os.path.sep
    emailtemplatefile = sep.join(["lib","Mail","mail.html"])
    email = EmailTemplate(result.visit(TestSuits()), emailtemplatefile)
    email.write_to_html()
    sender = EmailSending()
    sender.email_sending()
    print("Sending Successfully")

if __name__ == "__main__":
    main()





